﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using posttrackerAPI2.Models;
using posttrackerApi2.Models;
using posttrackerApi2.Models.TypesHelper;

namespace posttrackerApi2.Controllers
{
    public class TrackController : ApiController
    {
        private posttracker_db db = new posttracker_db();
        private const int GuestId = 4;
        //
        // GET: /Tracks/
        Product[] trackers = new Product[]{
        
            new Product {Id = 1, PlaceName = "Warsaw", State="Dispatched", Date = "2012-10-01", TrackNumber = "GE123456781WW", UserId = 1},
            new Product {Id = 2, PlaceName = "London", State="Customs", Date = "2012-10-08", TrackNumber = "9999 999 99", UserId = 2},
            new Product {Id = 3, PlaceName = "New-York", State="Arrived", Date = "2012-10-14", TrackNumber = "GE123456781WW", UserId = 1}
        };

        public Product GetTrackerById(int id)
        {
            var tracker = trackers.FirstOrDefault((p) => p.Id == id);
            if (tracker == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
            return tracker;
        }

        public IEnumerable<Product> GetTrackersByTrackNumber(string trackNumber)
        {
            return trackers.Where((p) => string.Equals(p.TrackNumber, trackNumber, StringComparison.OrdinalIgnoreCase));
        }

        public IEnumerable<Product> GetTrackersByUserId(int userId)
        {
            return trackers.Where((p) => int.Equals(p.UserId, userId));
        }

        // POST api/Track/GetTrackDataByTrackNum/
        [HttpPost]
        public HttpResponseMessage GetTrackDataByTrackNum(TrackDataInfoRequest request)
        {
            string trackNum = request.TrackNumber;

            try
            {
                var tmp2 = db.TrackNumbers
                    .Where(number => number.Number.ToUpper().Equals(trackNum.ToUpper()))
                    .Join(db.UserTracks, number => number.Id, track => track.TrackNumberId,
                          (number, track) => new { userId = track.UserId }).FirstOrDefault();

                // 
                if (tmp2 == null)
                {
                    return Request.CreateResponse(HttpStatusCode.NotFound);
                }
                else if (tmp2.userId != request.UserId) // если id текущего пользователя не совпадает с id пользователя которому принадлежит трек то
                {
                    return Request.CreateResponse(HttpStatusCode.NotAcceptable);
                }

                var tmp1 = db.TrackNumbers
                    .Where(number => number.Number.ToUpper().Equals(trackNum.ToUpper()))
                    .Join(db.TrackDatas, number => number.Id, data => data.TrackNumberId, (number, data) => new { number = number.Number, records = data.XmlDescription });

                int userId = tmp2 != null ? tmp2.userId : GuestId;

                IList<TrackDataInfoRequest> result = new List<TrackDataInfoRequest>();

                foreach (var element in tmp1)
                {
                    TrackDataInfoRequest trackDataInfoRequest = new TrackDataInfoRequest { TrackNumber = element.number, Records = element.records, UserId = userId };
                    result.Add(trackDataInfoRequest);
                }

                return Request.CreateResponse(HttpStatusCode.OK, result);
            }
            catch (WebException)
            {
                return Request.CreateResponse(HttpStatusCode.NotFound);
            }
            catch (HttpResponseException)
            {
                return Request.CreateResponse(HttpStatusCode.Accepted);
            }

        }

        // POST api/Track/GetTrackDataByUserId/
        [HttpPost]
        public HttpResponseMessage GetTrackDataByUserId(PutUserRequest request)
        {
            UserComming userComming = request.User;
            int userId = userComming.Id;
            try
            {
                var tmp = db.UserTracks
                    .Where(track => track.UserId == userId)
                    .Join(db.TrackNumbers, track => track.TrackNumberId, number => number.Id,
                               (track, number) => new { numberId = number.Id, num = number.Number })
                    .Join(db.TrackDatas, arg => arg.numberId, data => data.TrackNumberId,
                               (anonim, data) => new { number = anonim.num, records = data.XmlDescription });

                IList<TrackDataInfoRequest> result = new List<TrackDataInfoRequest>();

                foreach (var element in tmp)
                {
                    TrackDataInfoRequest trackDataInfoRequest = new TrackDataInfoRequest { TrackNumber = element.number, Records = element.records, UserId = userId };
                    result.Add(trackDataInfoRequest);
                }

                return Request.CreateResponse(HttpStatusCode.OK, result);
            }
            catch (WebException)
            {
                return Request.CreateResponse(HttpStatusCode.NotFound);
            }
            catch (HttpResponseException)
            {
                return Request.CreateResponse(HttpStatusCode.Accepted);
            }

        }

        public IEnumerable<Product> GetTrackersByPlace(string userId)
        {
            var pr = trackers
                .Where(e => e.Id >= 2 && e.PlaceName.ToLower().Contains("m"))
            .OrderByDescending(e => e.Id)
            .ToList<Product>();

            var pr1 = from e in trackers
                      where e.Id > 2
                      && e.PlaceName.ToLower().Contains("m")
                      orderby e.Id descending
                      select e;
            return trackers.Where((p) => int.Equals(p.UserId, userId));
        }


        [HttpPost]
        public HttpResponseMessage InsertTrackData(TrackDataInfoRequest request)
        {

            int userId = request.UserId;

            
            var res = db.TrackNumbers
                .Where(number => number.Number.Equals(request.TrackNumber, StringComparison.OrdinalIgnoreCase))
                .Select(number => new{id = number.Id}).FirstOrDefault();

            if (res != null) // проверяем существует ли трек
            {
                var tmp = db.TrackDatas
                    .Where(data => data.TrackNumberId == res.id).FirstOrDefault();
                    //.Select(data => new { XmlDescription = data.XmlDescription, DateFromParse = data.DateFromParse }).FirstOrDefault();

                if (tmp != null) // если инфа по треку существует обновляем ее
                {
                    tmp.DateFromParse = DateTime.Now.ToShortDateString();
                    tmp.XmlDescription = request.Records;

                    db.SaveChanges();
                }
                else // иначе создаем запись инфы по треку
                {
                    if (!string.IsNullOrEmpty(request.Records)) // если есть вообще какаято инфа для записи
                    {
                        // Заполняем инфу о треке
                        TrackData trackData = new TrackData
                        {
                            XmlDescription = request.Records,
                            DateAdd = DateTime.Now.ToShortDateString(),
                            DateFromParse = DateTime.Now.ToLongDateString(),
                            TrackNumberId = res.id
                        };

                        db.TrackDatas.Add(trackData);
                        // Записываем изменения
                        db.SaveChanges(); 
                    }

                }

            }
            else // иначе добавляем новый трек и привязывем его к юзеру
            {
                // Создаем трек
                TrackNumber track = db.TrackNumbers.Add(new TrackNumber { Number = request.TrackNumber });
                // Записываем изменения чтобы получить id записи для дальнейших действий
                db.SaveChanges();

                // Привязываем трек к юзеру
                UserTrack userTrack = new UserTrack
                {
                    TrackNumberId = track.Id,
                    UserId = request.UserId
                };

                db.UserTracks.Add(userTrack);

                if (!string.IsNullOrEmpty(request.Records))
                {
                    // Заполняем инфу о треке
                    TrackData trackData = new TrackData
                    {
                        XmlDescription = request.Records,
                        DateAdd = DateTime.Now.ToLongDateString(),
                        DateFromParse = DateTime.Now.ToLongDateString(),
                        TrackNumberId = track.Id
                    };

                    db.TrackDatas.Add(trackData); 
                }

                // Записываем изменения
                db.SaveChanges();
            }


            return Request.CreateResponse(HttpStatusCode.OK, true);
        }

    }
}